﻿<%@ Page Title="Tutorial #1" Language="VB" MasterPageFile="~/site.master" AutoEventWireup="false"
    CodeFile="tutorial1.aspx.vb" Inherits="tutorial1" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">

    <script type="text/javascript">
        function submitForm(userForm) {
            var data = userForm.getData();

            WebService.SubmitForm(data, submitForm_callback, error_callback);
        }
        function submitForm_callback(result) {
            if (result) {
                if (result.Success) {
                    alert('Form submitted successfully: ' + result.Greeting);
                } else {
                    alert('An error occured during the method call');
                }
            } else {
                alert('Failed to call the server method');
            }
        }
        function error_callback(msg) {
            alert('Failed');
        }     
    </script>

</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <h2>
        Tutorial #1</h2>
    <p>
        In this tutorial, designing a jObjective form is show and the jObjective.DataObject.getData() method is discussed.</p>
    <p>
        The page has a single ScriptWriter which we've called PageScriptWriter.  This page relies on a webservice at <a href="http://www.jobjective.net/WebService.asmx">http://www.jobjective.net/WebService.asmx</a>.  The service is bound to the Javascript XmlHttpRequest using the AJAX ScriptManager.
    </p>
    <h3>VB.NET</h3>
    <code>
        PageScriptWriter.ScriptManager.Services.Add(New ServiceReference(Common.ServicePath(Context) & "/WebService.asmx"))
    </code>
    <br />
    <p>
        The form which we will use to submit the data to the webservice comprises of a jdn:Panel and 4 jdn:TextBoxs
    </p>
    <h3>ASP.NET</h3>
    <code>
        &lt;jdn:Panel ID=&quot;UserFormSection&quot; runat=&quot;server&quot; ObjectName=&quot;UserForm&quot; CssClass=&quot;clear&quot;&gt;
        <br />&lt;div class=&quot;clear&quot;&gt;
        <br />        &lt;label class=&quot;fieldlabel&quot;&gt;
        <br />            First Name
        <br />        &lt;/label&gt;
        <br />        &lt;jdn:TextBox ID=&quot;FirstNameInput&quot; runat=&quot;server&quot; ObjectName=&quot;FirstName&quot;&gt;&lt;/jdn:TextBox&gt;
        <br />    &lt;/div&gt;
        <br />    &lt;div class=&quot;clear&quot;&gt;
        <br />        &lt;label class=&quot;fieldlabel&quot;&gt;       
        <br />            Last Name
        <br />        &lt;/label&gt;
        <br />        &lt;jdn:TextBox ID=&quot;LastNameInput&quot; runat=&quot;server&quot; ObjectName=&quot;LastName&quot;&gt;&lt;/jdn:TextBox&gt;
        <br />     &lt;/div&gt;
        <br />    &lt;div class=&quot;clear&quot;&gt;
        <br />        &lt;label class=&quot;fieldlabel&quot;&gt;
        <br />            Contact Number
        <br />        &lt;/label&gt;
        <br />        &lt;jdn:TextBox ID=&quot;ContactNumberInput&quot; runat=&quot;server&quot; ObjectName=&quot;ContactNumber&quot;&gt;&lt;/jdn:TextBox&gt;
        <br />    &lt;/div&gt;
        <br />    &lt;div class=&quot;clear&quot;&gt;
        <br />        &lt;label class=&quot;fieldlabel&quot;&gt;
        <br />            Email
        <br />        &lt;/label&gt;
        <br />        &lt;jdn:TextBox ID=&quot;EmailInput&quot; runat=&quot;server&quot; ObjectName=&quot;Email&quot;&gt;&lt;/jdn:TextBox&gt;
        <br />    &lt;/div&gt;
        <br />&lt;/jdn:Panel&gt;
    </code>
    <br />
    <p>
        There's a lot to discuss here.  Firstly, there's a new property, called 'ObjectName'.  This will coincedentally store the name of the javascript object.  
        This object will not, however, be in the global namespace, it will reside within the parent jObjective object.  
        All root level jObjective objects will exist within the Page object, which is created by the ScriptWriter control.
        At the end of the source code for this page, you will see the following javascript:
    </p>
    <h3>Javascript</h3>
    <code>
        var Page=new jObjective.DataObject();        <br />Page.UserForm=new jObjective.DataObject($('#C0'));        <br />Page.UserForm.FirstName=new jObjective.TextBox($('#C1'),null);        <br />Page.UserForm.LastName=new jObjective.TextBox($('#C2'),null);        <br />Page.UserForm.ContactNumber=new jObjective.TextBox($('#C3'),null);        <br />Page.UserForm.Email=new jObjective.TextBox($('#C4'),null);
    </code>
    <br />
    <p>
        Each object is a new instance of the jObjective.DataObject and the constructor is passed a jQuery selector for the HTML element. 
        Our jdn:Panel will now have a client side javascript object called UserForm which is in the Page object.
        Now if you're paying attention, you will have a question spring to mind, why is the jQuery selector looking for an element
        with the ID of <strong>C0</strong> when our Panel had an ID of <strong>UserFormSection</strong>?  There is a some what complicated reason for this,
        but a good one.  The way ASP.NET handles IDs is a bit <em>verbose</em>, I understand why they are handled in the way Microsoft decided, but
        I humbly believe there is a better way.  With jObjectiveDotNET controls, the IDs are generated using a counting hexadecimal number and the
        first letter C.  The ID is swapped for this incremental generated ID on the controls Load Event.  The effects are as follows:
    </p>
    <ul>
        <li>Designing the HTML and code behind can all be done using the ID you declare in the markup</li>
        <li>The controls still support postbacks as the ID is swapped before the PostBackData handler events just after the load event</li>
        <li>The ID of the controls in the Pre-Render events will be the ID of the control on the client, much like the ClientID property</li>
        <li>The rendered markup is now much cleaner and smaller.  This page is written using a MasterPage and it will no longer add the MasterPage control ID as a prefix to the jObjectiveDotNET controls</li>
        <li>The jQuery objects now have a much shorter string to locate in the DOM and the object instantiation is much shorter</li>
    </ul>
    <p>
        The only downside is that you must be careful when you use the ID property, but this has always been the case, 
        even with the ClientID property as it was determined by which controls collection the control belonged to and it wasn't necessarily static or predeterminable.
        A perfect example of why the ASP.NET control IDs are too verbose can be seen in the source for this page.  
        The ID of the submit button at the bottom of the page is <strong>ctl00_ContentPlaceHolder1_SubmitButton</strong>. <em>Verbose.</em>
    </p>
    <p>
        The final part of the tutorial is to have an event submit our form.  A input element with an onclick event will be used for this.
    </p>
    <h3>VB.NET</h3>
    <code>
        SubmitButton.OnClientClick = String.Format("submitForm({0}); return false;", UserFormSection.Namespace)
    </code>
    <br />
    <p>
        The onclick event is set in the code behind and the javascript function submitForm is passed a single important parameter.
        The Namespace.  All JDN controls have a Namespace property, this property is populated with its' value by the ScriptWriter
        during the Load Event.  The value is the full name of the javascript object and its' parents. i.e. The Email input element
        will have a Namespace of Page.UserForm.Email.  The onclick attribute will now be populated with 
    </p>
    <code>submitForm(Page.UserForm); return false;</code>
    <br />
    <p>
        The submitForm function now has a reference to the Page.UserForm object and can call all the methods on it directly.  
        Most importantly, it can call the <strong>getData()</strong> function.  The getData() function will recursively traverse
        through all the child DataObjects and return a JSON object with the same fundamental structure.  The best way to see what
        the object looks like is to use a javascript debugger like the Chrome Developer Tools, Firefox + Firebug or the Internet Explorer
        Developer Tools.
    </p>
    <p>
        Note: more information on what functions are available on the DataObject can be found in the <a href="https://code.google.com/p/jobjective/wiki/DataObject">wiki</a>
    </p>
    <p>
        Here is the form that has been discussed.  Seems innocent enough, but one has to learn to walk before they can run.
    </p>
    <h3>Final Result</h3>
    <div class="section" style="padding-top:5px;padding-bottom:5px;">
        <jdn:Panel ID="UserFormSection" runat="server" ObjectName="UserForm" CssClass="clear">
            <div class="clear">
                <label class="fieldlabel">
                    First Name
                </label>
                <jdn:TextBox ID="FirstNameInput" runat="server" ObjectName="FirstName"></jdn:TextBox>
            </div>
            <div class="clear">
                <label class="fieldlabel">
                    Last Name
                </label>
                <jdn:TextBox ID="LastNameInput" runat="server" ObjectName="LastName"></jdn:TextBox>
            </div>
            <div class="clear">
                <label class="fieldlabel">
                    Contact Number
                </label>
                <jdn:TextBox ID="ContactNumberInput" runat="server" ObjectName="ContactNumber"></jdn:TextBox>
            </div>
            <div class="clear">
                <label class="fieldlabel">
                    Email
                </label>
                <jdn:TextBox ID="EmailInput" runat="server" ObjectName="Email"></jdn:TextBox>
            </div>
        </jdn:Panel>
        <div class="clear">
            <label class="fieldlabel">
                &nbsp;</label>
            <asp:Button ID="SubmitButton" runat="server" Text="Submit Via AJAX" Width="160px" />
        </div>
    </div>
    <br />
    <p>
        And that's it, hope everything makes sense.  Thanks for following.
    </p>
    <p>
        If you'd like to ask a question or make a comment, please visit <a href="http://jobjective.blogspot.com/2011/02/tutorial-1-complete.html">the blog post</a>
    </p>
</asp:Content>
